<template>
    <div style="width: 100%">
        <el-upload
            :multiple="props.multiple"
            drag
            :action="uploadAction"
            :before-upload="beforeUpload"
            :http-request="handleUpload"
            :auto-upload="true"
            :file-list="fileList"
            :on-change="handleChange"
            :show-file-list="false"
            class="upload-file-uploader"
            ref="fileUpload"
            v-if="props.multiple"
        >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        </el-upload>
        <el-table
            ref="tableRef"
            :header-cell-style="{ 'text-align': 'center' }"
            :data="uploadFiles"
        >
            <el-table-column label="序号" type="index" width="50">
                <template #default="scope">{{ scope.$index + 1 }}</template>
            </el-table-column>
            <el-table-column prop="uid" v-if="true"/>
            <el-table-column label="文件名" prop="name"/>
            <el-table-column label="文件大小" prop="size" width="100px">
                <template #default="scope">{{ formatFileSize(scope.row.size) }}</template>
            </el-table-column>
            <el-table-column label="MD5唯一标识" prop="md5"/>
            <el-table-column label="状态" prop="status" width="100px">
                <template #default="scope">{{ uploadStatus[scope.row.status - 1]?.label }}</template>
            </el-table-column>
            <el-table-column label="进度" prop="progress">
                <template #default="scope">
                    <el-progress :text-inside="true" :stroke-width="20" :percentage="scope.row.progress"></el-progress>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="60px">
                <template #default="scope">
                    <el-tooltip content="删除" placement="top" v-if="scope.row.roleId !== 1">
                        <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
                    </el-tooltip>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue';
import { defineProps, ref, watchEffect, reactive } from 'vue';

const props = defineProps({
    multiple: Boolean,
    uploadFiles: {
        type: Array as () => Array<{ uid: string; name: string; size: number; md5: string; progress: number; status: number; filePath?: string; uploadWork: Worker; roleId?: number; }>,
        default: () => []
    }
});

const uploadFiles = reactive(props.uploadFiles);
const fileList = ref([]);
const uploadAction = ''; // 上传地址
const uploadStatus = [
    { label: '等待中', value: 1 },
    { label: '正在计算MD5', value: 2 },
    { label: '正在上传', value: 3 },
    { label: '完成', value: 4 },
    { label: '失败', value: 5 }
];

function setFileMd5(uid: string, md5: string) {
    // uploadFiles.find(file => file.uid === uid)?.update({ md5 });
    const file = uploadFiles.find(file => file.uid === uid);
    if(file){
        file.md5 = md5;
    }
}

function setFileProgress(uid: string, progress: number) {
    // uploadFiles.find(file => file.uid === uid)?.update({ progress });
    const file = uploadFiles.find(file => file.uid === uid);
    if(file){
        file.progress = progress;
    }
}

function setFileStatus(uid: string, status: number, filePath?: string) {
    const file = uploadFiles.find(file => file.uid === uid);
    if (file) {
        // file.update({ status, filePath });
        file.status = status;
        file.filePath = filePath;
        if (status === 2) file.progressColor = 'green';
        if (status === 3) file.progressColor = 'blue';
    }
}

function removeFile(uid: string) {
    const index = uploadFiles.findIndex(file => file.uid === uid);
    if (index !== -1) {
        uploadFiles[index].uploadWork.terminate();
        uploadFiles.splice(index, 1);
    }
}

function handleDelete(row: any) {
    const index = uploadFiles.findIndex(file => file.uid === row.uid);
    if (index !== -1) {
        uploadFiles[index].uploadWork.postMessage({ cmd: 2 });
    }
}

function handleUpload(param: { file: File }) {
    const uploadFile = {
        uid: param.file.uid,
        name: param.file.name,
        size: param.file.size,
        md5: '',
        progress: 0,
        status: 1,
        uploadWork: new Worker(new URL('@/workers/large-file-upload-worker.js', import.meta.url), { type: 'module' })
    };
    uploadFile.uploadWork.postMessage({ cmd: 1, uid: uploadFile.uid, file: param.file });
    uploadFile.uploadWork.onmessage = (e) => {
        const msgInfo = e.data;
        if (msgInfo.uid === null) console.log('收到的uid为空:', e.data.uid);
        if (msgInfo.type === 1) {
            if (msgInfo.status === 6) {
                removeFile(msgInfo.uid);
            } else {
                setFileStatus(msgInfo.uid, msgInfo.status, msgInfo.filePath);
                if (msgInfo.status === 3) setFileMd5(msgInfo.uid, msgInfo.md5);
            }
        } else if (msgInfo.type === 2) {
            setFileProgress(msgInfo.uid, msgInfo.progress);
        }
    };
    uploadFiles.push(uploadFile);
}

const formatFileSize = (bytes: number, decimalPoint: number = 2): string => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimalPoint))} ${sizes[i]}`;
};

// // 假设每个文件对象都有一个 update 方法来更新自身状态
// interface File extends Omit<ReturnType<typeof reactive>[number], 'uploadWork'> {
//     update(updates: Partial<this>): void;
// }

// // 为文件对象添加更新方法
// (uploadFiles as unknown as File[]).forEach(file => {
//     file.update = (updates: Partial<File>) => Object.assign(file, updates);
// });
</script>

<style lang="scss" scoped>
.upload-file-uploader {
    margin-bottom: 20px;
}
</style>